package cn.ztc.plugin.organism.controller;

import cn.hutool.core.lang.UUID;
import lombok.extern.slf4j.Slf4j;
import cn.hutool.crypto.digest.DigestUtil;
import com.google.common.cache.CacheLoader;
import com.google.common.cache.CacheBuilder;
import com.google.common.cache.LoadingCache;
import cn.ztc.plugin.organism.entity.Organism;
import cn.ztc.plugin.organism.mapper.OrganismMapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.Objects;
import javax.annotation.Nullable;
import javax.annotation.Resource;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.ExecutionException;

/**
 * 登录控制器
 *
 * @author ZhangTianCi
 */
@Slf4j
@RestController
@RequestMapping("/login")
public class LoginController {
    @Resource
    OrganismMapper organismMapper;
    /**
     * token缓存
     */
    private final LoadingCache<String, Organism> TOKEN_CACHE = CacheBuilder.newBuilder().maximumSize(3000)
            .expireAfterWrite(1, TimeUnit.HOURS).build(new CacheLoader<String, Organism>() {
                @Override
                public Organism load(@Nullable String name) {
                    log.info("尝试加载TOKEN缓存{}.", name);
                    return null;
                }
            });

    /**
     * 凭证登录
     *
     * @param name    名称
     * @param voucher 凭证
     *
     * @return 兑换码
     */
    @RequestMapping("voucher")
    public String login(@RequestParam(required = false) String name, @RequestParam(required = false) String voucher) {
        Organism organism = organismMapper.selectOne(Wrappers.lambdaQuery(Organism.class).eq(Organism::getName, name));
        if (Objects.nonNull(organism)) {
            String databaseVoucher = organism.getVoucher();
            if (DigestUtil.bcryptCheck(voucher, databaseVoucher)) {
                String token = UUID.randomUUID().toString(true);
                TOKEN_CACHE.put(token, organism);
                return token;
            }
        }
        return "";
    }

    @RequestMapping("check")
    public boolean checkToken(@RequestParam(required = false) String token) {
        Organism organism = null;
        try {
            return Objects.isNull(TOKEN_CACHE.get(token));
        } catch (ExecutionException e) {
            log.error("登录状态检查失败.", e);
            return false;
        }
    }
}
